
DevBar = function() {

    var DEVBAR_COOKIE   = 'devbar_history';
    var MESSAGE_DELIM   = ')=(';
    var LEVEL_DELIM     = ']=[';
    var DEVBAR_OPEN     = 'open';
    var DEVBAR_CLOSED   = 'closed';

    var loading         = false;
    var contract        = true;

    function disabled() {
        if ( ! DevBar.active ) {
            $('#devbar_expanded').hide();
            $('#devbar_contracted').hide();
        }

        return ! DevBar.active;
    }

    function loadMessageArray() {

        if ( ! DevBar.messageArray ) {
            var stashedMessages = (
                new String(
                    YAHOO.util.Cookie.getSub(
                        DEVBAR_COOKIE,
                        DEVBAR_COOKIE
                    )
                )
            ).toString().split( MESSAGE_DELIM );

            if ( stashedMessages ) return stashedMessages;
            return new Array();
        }
        else {
            return DevBar.messageArray;
        }
    }

    return {

        config  : {},
        active  : true,
        verbose : true,
        invade  : true,

        close : function() {
            if ( DevBar.logger ) DevBar.logger.hide();                        
            $('#devbar_closelink').hide();
            $('#devbar_openlink').show();

            DevBar.windowOpen = false;
            DevBar.flush();
        },

        open : function() {
            if ( DevBar.logger ) DevBar.logger.show();
            $('#devbar_closelink').show();
            $('#devbar_openlink').hide();

            DevBar.windowOpen = true;
            DevBar.flush();
        },

        clear : function() {
            YAHOO.widget.Logger.reset();
            DevBar.messageArray = new Array();
            DevBar.flush();
        },

        load : function() {

            if ( disabled() ) return;

            $(document).ready( function() {
                loading = true;

                // Each of the required page elements 
                $('body').append(
                    $('<div></div>').addClass('yui-skin-sam').append(
                        $('<div></div>').attr( 'id', 'devbar_logger' )
                    )
                ).append(
                    $('<div></div>')
                        .attr( 'id', 'devbar_expanded' )
                        .addClass( 'devbar_container devbar_big' )
                        .mouseout(
                            function() {
                                if ( ! $('#devbar_expanded').is(':hidden') ) DevBar.contract();
                            }
                        )
                        .hide()
                ).append(
                    $('<div></div>')
                        .attr( 'id', 'devbar_contracted' )
                        .addClass( 'devbar_container devbar_small devbar_opaque' )
                        .mouseover( DevBar.expand )
                ).append(
                    $('<div></div>')
                        .attr( 'id', 'devbar_message' )
                        .addClass( 'devbar_container devbar_message' )
                        .hide()
                );

                // Setup the DOM before we start attaching stuff to it
                DevBar.register( { 
                    label : 'Logger',
                    links : [
                        $('<a>Clear</a>')
                            .attr( 'href', 'javascript:void(0);' )
                            .click( DevBar.clear ),

                        $('<span>| </span>'),

                        $('<a>Open</a>')
                            .attr( 'href', 'javascript:void(0);' )
                            .click( DevBar.open )
                            .attr( 'id', 'devbar_openlink' )
                            .hide(),

                        $('<a>Close</a>')
                            .attr( 'href', 'javascript:void(0);' )
                            .click( DevBar.close )
                            .attr( 'id', 'devbar_closelink' )
                            .show()
                    ]
                } );

                DevBar.contract();
                DevBar.logger = new YAHOO.widget.LogReader( 'devbar_logger', DevBar.config );

                var windowState = YAHOO.util.Cookie.getSub( DEVBAR_COOKIE, 'devbar_state' );
                ( windowState == DEVBAR_OPEN ) ? DevBar.open() : DevBar.close();

                var stashedMessages = (
                    new String(
                        YAHOO.util.Cookie.getSub(
                            DEVBAR_COOKIE,
                            DEVBAR_COOKIE
                        )
                    )
                ).toString().split( MESSAGE_DELIM );

                for ( var i in stashedMessages ) {
                    var info = stashedMessages[i].split( LEVEL_DELIM );
                    if ( info[0] && info[1] ) DevBar.log( info[1], info[0] );
                }

                if ( DevBar.invade ) {

                    // Invade jQuery
                    jQuery.fn.extend( {
                        log : DevBar.log
                    } );

                    // Invade YUI
                    var children = $('#devbar_logger input');
                    for ( var i in children ) {
                        if ( children[i].value == 'Clear' ) {

                            $( document.createElement('input') )
                                .attr( 'type', 'button' )
                                .attr( 'value', 'Close' )
                                .click( DevBar.close )
                                .appendTo( 
                                    $( children[i].parentNode )
                                        .click( DevBar.clear )
                                );


                            break;
                        }
                    }

                    $( children[ children.length - 1 ].parentNode ).append(
                        $('<input type="checkbox">Verbose</input>')
                            .attr( 'checked', DevBar.verbose )
                            .attr( 'id', 'devbar_verbose_toggle' )
                            .change( function() {
                                DevBar.verbose = ! DevBar.verbose;
                                $('#devbar_verbose_toggle').attr( 'checked', DevBar.verbose );
                            } )
                    );
                }

                loading = false;
                return;
            } );
        },

        register : function( instructions ) {

            if ( ! instructions.label ) 
                throw('"label" is required attribute of "DevBar.register" instructions.');

            var span = $('<span>' + instructions.label + ' :: </span>' ).appendTo('#devbar_expanded');

            var last  = span;
            for ( var i in instructions.links ) { 
                last.mouseover( function() { contract = false; } );
                last.mouseout(  function() { contract = true; } );
                instructions.links[i].appendTo(last); 
            }
             
        },

        expand : function() {
            if ( disabled() ) return;

            $('#devbar_contracted').hide();
            $('#devbar_expanded').fadeIn('fast');
            $('#devbar_message').addClass('devbar_message_adjusted');
        },

        contract : function() {
            if ( disabled() ) return;

            if ( DevBar.timer ) clearTimeout( DevBar.timer );

            if ( ! $('#devbar_expanded').is(':hidden') ) {
                DevBar.timer = setTimeout( 
                    function() {
                        if ( contract ) {
                            $('#devbar_contracted').show();
                            $('#devbar_expanded').fadeOut('fast');
                            $('#devbar_message').removeClass('devbar_message_adjusted');
                        }
                    },
                    1000
                );
            }
        },

        flush: function() {
            if ( ! DevBar.messageArray ) DevBar.messageArray =  loadMessageArray();

            YAHOO.util.Cookie.setSubs(
                DEVBAR_COOKIE,
                { 
                    devbar_history : DevBar.messageArray.join( MESSAGE_DELIM ), 
                    devbar_state   : ( DevBar.windowOpen == false ) ? DEVBAR_CLOSED : DEVBAR_OPEN
                },
                { 
                    path: '/' 
                }
           );
        },

        log : function( message, level ) {

            if ( ! message ) return;
            if ( ! level ) level = 'info';
            if ( ! DevBar.messageArray ) DevBar.messageArray = loadMessageArray() 

            DevBar.messageArray.push( ( new Array( level, message ) ).join( LEVEL_DELIM ) );
            YAHOO.log( message, level );
            DevBar.flush();

            if ( DevBar.verbose && ! loading ) {
                $('#devbar_message')
                    .fadeIn('fast')
                    .html( level.toUpperCase() + ': ' + message )
                    .addClass( 'devbar_message_' + level )
                    .mouseover(
                        function() { 
                            $('#devbar_message').fadeOut('slow') 
                        } 
                );

                if ( DevBar.verboseTimer ) clearTimeout( DevBar.verboseTimer );
                DevBar.verboseTimer = setTimeout(
                    function() {
                        if ( ! $('#devbar_message').is(':hidden') )
                            $('#devbar_message').fadeOut('slow');
                    },
                    5000
                );
            }
        }
    };
}();

DevBar.load();
